<?php

namespace SunAdmin\Middleware;

use SunAdmin\Common\ResponseJson;
use SunAdmin\Common\TokenHelper;
use SunAdmin\Model\AccountGroupModel;
use SunAdmin\Model\AccountModel;
use think\Request;
use Closure;
class Auth
{
    // 不需要验证的路由（支持 URI 开头匹配）
    protected array $except = [
        'sunadmin/account/login',
        'sunadmin/account/loginOut',
        'admin/print/callback/print_result',
        'admin/print/callback/device_status',
    ];
    public function handle(Request $request, Closure $next)
    {
        $path = strtolower($request->pathinfo());
        // 检查是否在排除列表
        foreach ($this->except as $except) {
            // 只允许以 except 完整匹配或$except 的值（不区分大小写）开头，并且后面紧跟着一个 /
            if ($path === strtolower($except) || preg_match('#^' . preg_quote(strtolower($except)) . '/#', $path)) {
                return $next($request);
            }
        }
        // 获取 Authorization: Bearer <token>
        $authHeader = $request->header('authorization');
        //没有header认证参数时,从url参数中取token认证
        if (!$authHeader) {
            $token = $request->param('token');
            $authHeader = $token ? "Bearer $token" : '';
        }
        if (!$authHeader || !str_starts_with(strtolower($authHeader), 'bearer ')) {
            return ResponseJson::error('未登录，请先登录',401);
        }

        $token = substr($authHeader, 7);
        $tokenToUser = TokenHelper::verify($token);

        if (!$tokenToUser) {
            return ResponseJson::error('登录已过期，请重新登录',401);
        }
        $userInfo = AccountModel::find($tokenToUser['uid']);
        if (!$userInfo) {
            return ResponseJson::error('请先登录',401);
        }
        if(!$userInfo['status']){
            return ResponseJson::error('账号已被禁用,请联系管理员',401);
        }
		if (!$userInfo['is_administrators']) {
			$accountGroup = AccountGroupModel::where('id', $userInfo['group_id'])->find();
			if (!$accountGroup) {
				return ResponseJson::error('账号权限组有误',401);
			}
			if(!$accountGroup->status){
				return ResponseJson::error('账号权限组已被禁用',401);
			}
		}
		
        // 设置管理员会话信息
        $request->adminUid = $userInfo['id'];
        $request->adminUser = $userInfo;
        $request->adminToken = $token;
        return $next($request);
    }
}